<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>es6</title>
    </head>
    <body>
        <input type="button" onclick="show()" value="弹窗"/>
        <br/>
        <input type="button" onclick="for1()" value="循环"/>
        <br/>
        <input type="button" onclick="for2()" value="循环2"/>
        <br/>
        <input type="button" onclick="show2()" value="输出"/>
        <br/>
        <input type="button" onclick="show3()" value="变量提升"/>
        <br/>
        <input type="button" onclick="show4()" value="暂时性死区"/>
        <br/>
        <input type="button" onclick="show5()" value="隐蔽死区"/>
        <br/>
        <input type="button" onclick="show6()" value="非死区，正确写法"/>
        <br/>
        <input type="button" onclick="show7()" value="块级作用域"/>
        <br/>
        <input type="button" onclick="show9()" value="块级作用域2"/>
        <br/>
        <input type="button" onclick="show10()" value="块级作用域与函数声明"/>
        <br/>
        <input type="button" onclick="show11()" value="const"/>
        <br/>
        <input type="button" onclick="show12()" value="const对象"/>
        <br/>
        <input type="button" onclick="show13()" value="const对象2"/>
        <br/>
        <input type="button" onclick="show14()" value="对象冻结"/>
        <br/>
        <input type="button" onclick="show15()" value="== ==="/>


    </body>
</html>

<script type="text/javascript">
    function show() {
        alert(a)
    }

    {
        //let只在块内有效，var可以在块外
        var a = 6;
        let b = 10;
    }


    function for1() {
        for (let i = 0; i < 10; i++) {
            console.log(i)
        }
        // console.log(i)
    }

    function for2() {
        for (let i = 0; i < 3; i++) {
            let i = "abc";
            console.log(i)
        }
    }

    function show2() {
        var a = [];
        for (var i = 0; i < 10; i++) {
            a[i] = function () {
                console.log(i);
            };
        }
        a[0]();
    }

    function show3() {
        //var 变量后声明会输出undefined
        console.log(a);
        var a = "a"

        //let 变量后声明会报错
        console.log(b)
        let b = "b"
    }

    function show4() {
        temp = 'abc'    //报错，在let变量声明之前，该变量是不可用的，成为暂时性死区（temporal dead zone，简称 TDZ）
        console.log(temp)

        let temp        //TDZ结束
        console.log(temp)

        temp = 123
        console.log(temp)
    }

    function show5() {
        function bar(x = y, y = 2) {
            return [x, y]
        }

        bar()
    }

    function show6() {
        function bar(x = 2, y = x) {
            return [x, y]
        }

        bar()
    }

    function show7() {
        //变量提升，f()里边的tmp，后边定义的tmp会覆盖全局变量tmp，所以输出undefined
        var tmp = new Date();

        function f() {
            console.log(tmp);
            if (false) {
                var tmp = 'hello world';
            }
        }

        f();
    }

    function show8() {
        var s = 'hello';

        for (var i = 0; i < s.length; i++) {
            console.log(s[i]);
        }

        console.log(i);
    }

    function show9() {
        function f1() {
            let n = 5;
            if (true) {
                let n = 10;//let只在块内生效
            }
            console.log(n); // 5
        }

        function f2() {
            var n = 5;
            if (true) {
                var n = 10;//let只在块内生效
            }
            console.log(n); // 10
        }

        // f1()
        f2()
    }

    function show10() {
        /*
          //ES5中非法声明
          if (true) {
              function f() {

              }
          }

          //ES5中非法声明
          try {
              function f() {

              }
          } catch (e) {

          }
         */
        function f() {
            console.log('I am outside!');
        }

        (function () {
            if (false) {
                // 重复声明一次函数f
                function f() {
                    console.log('I am inside!');
                }
            }

            f();
        }());
    }

    function show11() {
        const a = 4;//const值声明就不可改变，而且在声明时必须赋值, 相当于final

        if (true) {
            const MAX = 10;
        }
        alert(MAX)//只在块作用域中生效
    }

    function show12() {
        //const指向的对象内存地址是不变的，但是对象的值可以改变
        const f = {}
        f.prop = 123
        f.prop

        // f = {} //报错 不能重复赋值
    }

    function show13() {
        const a = [];
        a.push('Hello'); // 可执行
        a.length = 0;    // 可执行
        // a = ['Dave'];    // 报错
    }

    function show14() {
        'use strict';//严格模式
        const foo = Object.freeze({});

        // 常规模式时，下面一行不起作用；
        // 严格模式时，该行会报错
        foo.prop = 123;
        console.log(foo)
    }

    function show15() {
        let a = 0;
        let b = '0';
        let c = "0";
        console.log(a == b);
        console.log(a == c);
        console.log(b == c);

        console.log(a === b);
        console.log(a === c);
        console.log(b === c);
    }


</script>